﻿using System;
using System.Web;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Mr.HttpBodyWrapper
{
    public class MultipartHttpBodyWrapper : HttpBodyWrapperBase
    {
        private Random NumGenerator = new Random();

        public MultipartHttpBodyWrapper(params IParameter[] parameters)
            : base(parameters)
        {
            this.wrapper = "---------------------------" + Convert.ToString(NumGenerator.Next(0, int.MaxValue));
            this.contentType = string.Format("{0}", "multipart/form-data; boundary=" + this.wrapper);
        }

        private string wrapper;

        private string contentType;

        public override string ContentType
        {
            get
            {
                return contentType;
            }
        }
        public override byte[] ToBodyData()
        {
            using (MemoryStream ms = new MemoryStream())
            {

                if (this.ParamsCount > 0)
                {
                    StreamWriter sw = new StreamWriter(ms);

                    foreach (IParameter ip in this.Parameters)
                    {
                        IQueryParameter qp = ip as IQueryParameter;
                        IFileParameter fp = ip as IFileParameter;
                        byte[] value = null;

                        sw.Write(string.Format("--{0}\r\n", this.wrapper));
                        if (qp != null)
                        {
                            sw.Write(string.Format("Content-Disposition: form-data; name=\"{0}\"", qp.Name));
                            value = Encoding.UTF8.GetBytes(
                                HttpUtility.UrlDecode(qp.Value));
                        }
                        else if (fp != null)
                        {
                            sw.Write("Content-Disposition: form-data");
                            if (!string.IsNullOrEmpty(fp.Name))
                            {
                                sw.Write(string.Format("; name=\"{0}\"", fp.Name));
                            }
                            sw.Write(string.Format("; filename=\"{0}\"", fp.FileName));

                            value = fp.FileData;
                        }

                        if (value == null)
                        {
                            continue;
                        }

                        sw.Write("\r\n");
                        sw.Write(string.Format("Content-Type:{0}", ip.ContentType));

                        sw.Write("\r\n\r\n");
                        sw.Flush();

                        ms.Write(value, 0, value.Length);
                        sw.Write("\r\n");
                    }
                    sw.Write(string.Format("\r\n--{0}--", this.wrapper));

                    // must close
                    sw.Close();
                }
                return ms.ToArray();
            }
        }
    }
}
